package com.ma.a13;

import org.springframework.cglib.core.Signature;

/**
 * @ClassName TargetFastClass
 * @Author: mayongqiang
 * @DATE 2022/4/10 23:19
 * @Description: 配合目标使用
 */
/*
    在创建MethodProxy时就会生成FastClass
        eg:  MethodProxy.create(Target.class, Proxy.class, "()V", "save", "saveSuper");
        所谓的方法签名就是方法的信息  ()V  save

 */
public class TargetFastClass {
    static Signature s0 = new Signature("save", "()V");
    static Signature s1 = new Signature("save", "(I)V");
    static Signature s2 = new Signature("save", "(J)V");

    /*
        获取一个目标方法的编号,根据方法的签名信息        Signature 包括方法的名字,参数,返回值....

        Target
            save()            0
            save(int)         1
            save(double)      2
    */
    public int getIndex(Signature signature) {
        if (s0.equals(signature)) {
            return 0;
        } else if (s1.equals(signature)) {
            return 1;
        } else if (s2.equals(signature)) {
            return 2;
        }
        return -1;
    }

    /*
        根据getIndex返回的方法编号,正常调用目标对象的方法
     */
    public Object invoke(int index, Object target, Object[] args) {
        if (index == 0) {
            ((Target) target).save();
            return null;
        } else if (index == 1) {
            ((Target) target).save((int) args[0]);
            return null;
        } else if (index == 2) {
            ((Target) target).save((long) args[0]);
            return null;
        } else {
            throw new RuntimeException("无此方法");
        }
    }

    public static void main(String[] args) {
        /* 模拟 */
        // 首次使用MethodProxy的方法时救会自动创建fastClass
        TargetFastClass fastClass = new TargetFastClass();
        // MethodProxy记录了方法信息，可以得到方法编号
        int index = fastClass.getIndex(new Signature("save", "(I)V"));
        System.out.println(index);
        // 根据编号调用invoke方法
        fastClass.invoke(index, new Target(), new Object[]{100});
    }
}
